/*******************************************************************************
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *  
 * Copyright (c) 2011 Michael Chan.
 ******************************************************************************/
package com.google.code.solrdimension.querymodifiers;

import java.util.Arrays;
import java.util.List;

import org.apache.solr.client.solrj.SolrQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.code.solrdimension.config.QueryParamConstants;
import com.google.code.solrdimension.config.DimensionConfigWrapper;
import com.google.code.solrdimension.config.StaticConfiguration;
import com.google.code.solrdimension.config.dimension.DimensionConfig;
import com.google.code.solrdimension.config.dimensionvalue.ExactDimensionValueConfig;
import com.google.code.solrdimension.parsers.exception.SolrDimensionException;
import com.google.code.solrdimension.solrqueryutil.QueryUtil;

public class QueryModifierImpl implements QueryModifier {

    private static Logger logger = LoggerFactory.getLogger(QueryModifierImpl.class);
    

    public SolrQuery prepareQuery(SolrQuery query, DimensionConfigWrapper solrDimensionConfig) throws SolrDimensionException{
        
        if (query == null || solrDimensionConfig == null){
            throw new SolrDimensionException("Expecting SolrQuery and SolrDimensionConfig, but get null");
        } else {
            query.setFacet(true);
            
            List<String> filters = null;
            
            if (query.getFilterQueries() != null){
                filters = Arrays.asList(query.getFilterQueries());
            }
            
            
            for (DimensionConfig dimensionConfig :  solrDimensionConfig.getDimensionConfigs()){

                //first check if the DimesnionConfig should appear (i.e. The dependOn attribute in the XML file
                //is fulfilled
                if (dimensionConfig.getDependOn() == null || QueryUtil.isDimensionIdInFilter(dimensionConfig.getDependOn(), filters)){
                   
                    
                    
                    if (logger.isDebugEnabled()){
                        if (dimensionConfig.getDependOn() != null &&  QueryUtil.isDimensionIdInFilter(dimensionConfig.getDependOn(), filters)){
                            logger.debug("The DimensionConfig: " + dimensionConfig.getDisplayName() + " is depend on dimensionConfig with ID: " + dimensionConfig.getDependOn());
                        }
                    }
                    
                    String facetFieldName = null;
                    
                    if (dimensionConfig.getType().equals(DimensionConfig.TYPE_DEFAULT)){
                        facetFieldName = dimensionConfig.getSolrFieldName();
                    } else {
                        
                        if (dimensionConfig.getDimensionValueConfigs().get(0) instanceof ExactDimensionValueConfig){
                            facetFieldName = StaticConfiguration.FIELD_PREFIX + dimensionConfig.getId();
                        } else {
                            facetFieldName = StaticConfiguration.MULTI_VALUED_FIELD_PREFIX + dimensionConfig.getId();
                        }
                        
                    }
                    
                    query.addFacetField(facetFieldName);
                    
                    if (dimensionConfig.getValueOrder() != null){
                        
                        String paramName = QueryParamConstants.FACET_SORT_QUERY.replaceAll(QueryParamConstants.FACET_SORT_QUERY_REPLACE, facetFieldName);
                        
                        if (dimensionConfig.getValueOrder().equals(DimensionConfig.INDEX_VALUE_ORDER)){
                            
                            query.add(paramName, QueryParamConstants.FACET_SORT_INDEX_VAL);
                        } else if (dimensionConfig.getValueOrder().equals(DimensionConfig.FREQUENCY_VALUE_ORDER)){
                            query.add(paramName, QueryParamConstants.FACET_SORT_COUNT_VAL);
                        }
                    }
                    
                } else {
                    if (logger.isDebugEnabled()){
                        if (dimensionConfig.getDependOn() != null){
                            logger.debug("DimensionConfig: " + dimensionConfig.getDisplayName() + " is depend on " + dimensionConfig.getDependOn() + ", which is not in the filter: " + (filters==null?"":filters) );
                            
                            
                        }
                    }
                    
                }
                
            }
        }
        
        
        return query;
        
    }
    

    
}
